package cn.edu.scau.cmi.ema.service;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import cn.edu.scau.cmi.ema.domain.Filler;
import cn.edu.scau.cmi.ema.domain.Foodbatch;
import cn.edu.scau.cmi.ema.domain.Foodbatchfiller;
import cn.edu.scau.cmi.ema.domain.Unit;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.*;
@Service("FoodbatchfillerService")
@Transactional

public class FoodbatchfillerServiceImpl extends CmiEmaService implements FoodbatchfillerService {
	public FoodbatchfillerServiceImpl() {
	}

	@Transactional
	public Foodbatchfiller saveFoodbatchfiller(Foodbatchfiller foodbatchfiller) {

		if (foodbatchfiller.getId() == null) {
			Filler filler = fillerDAO.findFillerById(foodbatchfiller.getFiller().getId());
			Foodbatch foodbatch = foodbatchDAO.findFoodbatchById(foodbatchfiller.getFoodbatch().getId());
			Unit unit = unitDAO.findUnitById(foodbatchfiller.getUnit().getId());

			Foodbatchfiller existingFoodbatchfiller = foodbatchfillerDAO.findFoodbatchfillerByPhysicalPrimaryKey(
					foodbatch.getId(), filler.getId());

			foodbatchfiller.setFiller(filler);
			foodbatchfiller.setFoodbatch(foodbatch);
			foodbatchfiller.setUnit(unit);

			if (isEquals(foodbatchfiller, existingFoodbatchfiller)) {
				return existingFoodbatchfiller;
			}

			foodbatchfiller = foodbatchfillerDAO.store(foodbatchfiller);
			foodbatchfillerDAO.flush();

		} else {
			Foodbatchfiller existingFoodbatchfiller = foodbatchfillerDAO
					.findFoodbatchfillerByPrimaryKey(foodbatchfiller.getId());

			foodbatchfiller = foodbatchfillerDAO.store(foodbatchfiller);
			foodbatchfillerDAO.flush();
		}

		return foodbatchfiller;
	}

	public void deleteFoodbatchfiller(Foodbatchfiller foodbatchfiller) {
		foodbatchfillerDAO.remove(foodbatchfiller);
		foodbatchfillerDAO.flush();
	}

	@Transactional
	public void deleteFoodbatchfillers(Set<Integer> deleteFoodbatchfillersId) {
		Query query = foodbatchfillerDAO.createNamedQuery("deleteFoodbatchfillersById", -1, -1);
		query.setParameter(1, deleteFoodbatchfillersId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Foodbatchfiller> loadFoodbatchfillers() {
		return foodbatchfillerDAO.findAllFoodbatchfillers();

	}

	@Transactional
	public Set<Foodbatchfiller> loadReferenceFoodbatchfillers(Set<Foodbatchfiller> foodbatchfillers) {
		Iterator<Foodbatchfiller> foodbatchfillersIterator = foodbatchfillers.iterator();
		Set<Foodbatchfiller> referencedFoodbatchfillers = new HashSet<>();
		while (foodbatchfillersIterator.hasNext()) {
			Foodbatchfiller currentFoodbatchfiller = foodbatchfillersIterator.next();

		}
		return referencedFoodbatchfillers;
	}

	public Set<Foodbatchfiller> loadFoodbatchfillersByIdSet(Set<Integer> foodbatchfillerIdSet) {

		Iterator<Integer> foodbatchfillerIdIterator = foodbatchfillerIdSet.iterator();
		Set<Foodbatchfiller> foodbatchfillerSet = new HashSet<>();
		while (foodbatchfillerIdIterator.hasNext()) {
			Integer id = foodbatchfillerIdIterator.next();
			Foodbatchfiller currentFoodbatchfiller = foodbatchfillerDAO.findFoodbatchfillerById(id);
			foodbatchfillerSet.add(currentFoodbatchfiller);
		}
		return foodbatchfillerSet;
	}

	@Transactional
	public List<Foodbatchfiller> findAllFoodbatchfillers(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Foodbatchfiller>(
				foodbatchfillerDAO.findAllFoodbatchfillers(startResult, maxRows));
	}

	@Transactional
	public Foodbatchfiller findFoodbatchfillerByPrimaryKey(Integer id) {
		return foodbatchfillerDAO.findFoodbatchfillerByPrimaryKey(id);
	}

	@Transactional
	public Integer countFoodbatchfillers() {
		return ((Long) foodbatchfillerDAO.createQuerySingleResult("select count(o) from Foodbatchfiller o")
				.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countFoodbatchfillers(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Foodbatchfiller.class);
		return ((Long) foodbatchfillerDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 *
	 */
	@Transactional
	public Integer countFoodbatchfillersByName(String queryName) {
		Query query = foodbatchfillerDAO.createNamedQuery("countFoodbatchfillersByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countFoodbatchfillersByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Foodbatchfiller.class);
		Session session = (Session) entityManager.getDelegate();
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadFoodbatchfillerObjectReferencedSet(Foodbatchfiller foodbatchfiller) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();
		if (foodbatchfiller.getFiller() != null) {

			Set<Integer> fillerIds = new HashSet<Integer>();
			fillerIds.add(foodbatchfiller.getFiller().getId());
			objectReferencedSetMap.put("fillerIds", fillerIds);
		}
		if (foodbatchfiller.getFoodbatch() != null) {

			Set<Integer> foodbatchIds = new HashSet<Integer>();
			foodbatchIds.add(foodbatchfiller.getFoodbatch().getId());
			objectReferencedSetMap.put("foodbatchIds", foodbatchIds);
		}
		if (foodbatchfiller.getUnit() != null) {

			Set<Integer> unitIds = new HashSet<Integer>();
			unitIds.add(foodbatchfiller.getUnit().getId());
			objectReferencedSetMap.put("unitIds", unitIds);
		}

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadFoodbatchfillerClassReferencedSet(Foodbatchfiller foodbatchfiller) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("fillers", fillerDAO.findAllFillers());
		classReferencedSetMap.put("foodbatchs", foodbatchDAO.findAllFoodbatchs());
		classReferencedSetMap.put("units", unitDAO.findAllUnits());

		return classReferencedSetMap;
	}

	public boolean isEquals(Foodbatchfiller foodbatchfiller, Object obj) {
		if (obj == foodbatchfiller)
			return true;
		if (!(obj instanceof Foodbatchfiller))
			return false;
		Foodbatchfiller comparedFoodbatchfiller = (Foodbatchfiller) obj;
		if (!CheckPropertyEqual(foodbatchfiller.getFoodbatch().getId(),
				comparedFoodbatchfiller.getFoodbatch().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(foodbatchfiller.getFiller().getId(), comparedFoodbatchfiller.getFiller().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(foodbatchfiller.getQuantity(), comparedFoodbatchfiller.getQuantity())) {
			return false;
		}
		if (!CheckPropertyEqual(foodbatchfiller.getUnit().getId(), comparedFoodbatchfiller.getUnit().getId())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

